<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../css/reset.css">
    <script src="../js/vue.js"></script>
    <style>
        li {
            line-height: 40px;
            text-indent: 16px;
            border: 1px dashed #333;
        }
    </style>
</head>

<body>
    <div id="app">
        <p>
            <button @click="sortHandler">排序</button>
            <button @click="addHandler">新增元素</button>
            <button @click="editHandler">修改元素</button>
            <button @click="delHandler">删除元素</button>
        </p>
        <ul>
            <li v-for="(item,index) in list" :key="index">{{item}}</li>
        </ul>
    </div>
</body>
<script>

    // Vue 检测数组和对象的变化

    // Vue中 检测数据(data)中属性的变化,是依赖于数据劫持 Object.defineProperty()  => getter setter
    //     默认情况下,Vue是无法检测数组和对象的改变, 如果data中的属性对应的值是数组和对象时, 直接修改原数组/对象, data中该属性引入的地址没有改变 -> Vue是无法检测数组和对象的改变

    // 官方处理
    // 针对数组  => 数组更新检测   
    // 官方将数组的方法进行了分类: a. 影响原数组的方法 

    // 1. 变更方法(影响原数组的方法) => Vue 将被侦听的数组的变更方法进行了包裹，所以它们也将会触发视图更新
    // push unshift  pop shift splice reverse sort 

    // 2. 替换数组  => 非变更方法(不影响原数组的方法,而是返回新数组)  => 用新数组覆盖原本的数组  =>
    // concat()  slice()  map()  filter()  

    // 3. Vue无法检测数组以下变化
    //    list[0] = 100;
    //    list.length--;


    // Object.defineProperty(data, "list", {
    //     get: function () { // 取值拦截
    //         console.log("data取值拦截",key);
    //         return defaultValue;
    //     },
    //     set: function (val) { // 赋值拦截
    //         console.log("data赋值拦截",key,val);
    //         defaultValue = val;

    //         render(); // 数据发生改变之后 -> 重新渲染
    //     }
    // })

    var app = new Vue({
        el: "#app",
        data: {
            list: [1, 4, 7, 2, 5, 8, 3, 6, 9],
        },
        methods: {
            sortHandler() {
                this.list.sort((a, b) => a - b);  // 数组排序  => 直接修改员数组的值
            },
            addHandler() {
                var num = Math.round(Math.random() * 30);

                // this.list.push(num);

                this.list = this.list.concat(num);
            },
            editHandler() {
                // 对于下标赋值  -> 直接修改原数组,Vue无法检测,视图就不更新
                // this.list[0] = 100;
                // console.log(111, this.list);

                // 解决方案
                // 1. 使用splice => Vue可以检测
                // this.list.splice(0, 1, 100);

                // 2. 使用Vue提供的修改数据的方法(对象)    数组也是一个特殊的对象
                //    Vue.set(data,key,val)    构造函数Vue的静态方法
                //    this.$set(data,key,val) 
                // this.$set(this.list, 0, 100);

                // 3. 强制视图更新
                this.list[0] = 100;
                this.$forceUpdate();
            },
            delHandler() {
                // this.list.length--;  // 直接修改原数组,Vue无法检测,视图就不更新
                // console.log(2222, this.list);

                // 解决方案:
                // 1. 使用pop => Vue可以检测
                // this.list.pop();

                // 2. 强制视图更新
                this.list.length--;
                this.$forceUpdate();
            }
        }
    })
    console.log(app);


</script>

</html>